Pulse Width Modulation (PWM) initialization Here is the sequence, in 8 easy steps, required to start up the PWM circuit. Note that a 12Mhz oscillator is assumed and the VPB divider is set to its default divide by 4. Thus the clock frequency coming into the pre-scaler is 3 Mhz. Setting the prescaler to divide by 3 yields a 1 Mhz PCLK that is then counted by the PWM counter (1 microsecond per clock tick). (The complete details of the PWM circuit and its programming are found in chapter 16, pp 253 on, in the NXP LPC2148 Users Manual that can be found on the class web page.) For each step below, the process is to load the address of the specified PWM register into a CPU register, load another CPU register with the value to be written into the PWM register, and then do a Store to the value in the PWM register. Recall that the PWM registers are memory mapped, i.e. they are accessed by using memory addresses. For example: LDR r0,=PWM_PR ; get the address of the PWM_PR register LDR r1,=2 ; value to load into prescaler STR r1,[r0] where it is assumed that the PWM_PR value is defined with an EQU statement. (For this document, and the example programs and subroutines, I have placed an underscore between PWM and the remainder of the register name to make them easier to read.) 1) Write a value of 2 to PWM_PR, the pre-scaler (causes divide by three) 2) Write a value of 2 to PWM_MCR. This configures the counter to be reset when its count matches the PWM_MR0 register. 3) Write a value to PWM_MR0. 20,000 (20 ms) for driving the motors. Possibly 2,000,000 (two seconds) for debugging using LEDs. This sets the pulse period. 4) Write a value to PWM_MR4 to set PWM4 output pulse width. 1500 for motor "stopped" (this is approximate) possibly 500,000 for a 0.5 second width for visible debugging 5) Write a value to PWM_MR6 to set PWM6 output pulse width. Possibly 1,500,000 for visible debugging (can be distinguished from PWM4 that way) 6) Write a value of 0x51 to PWM_LER to enable latch registers for MR0, MR4, and MR6. (bits 0, 4, and 6 are set) 7) Write a value of 0x5000 to PWM_PCR to enable PWM4 and PWM6 outputs. (bits 12 & 14 are set) 8) Write a value of 0x09 to PWM_TCR to enable the counter & pre-scaler That completes the PWM set up itself. One more thing must be done. The PWM4 & PWM6 need to be selected for output rather than general I/O on the two physical pins P0.8 and P0.9. 9) Write a value of 0xA0000 (bits 19 & 17 set) to PINSEL0 If the program is running there should now be output pulses on those two pins. To change pulse width on PWM4 or PWM6, write a new value to PWM_MR4 or PWM_MR6 (or both) and then write a one to bit 4 or bit 6 (or both if both registers were loaded) to PWM_LER i.e., 0x10 for just MR4 0x40 for just MR6 0x50 when both MR4 and MR6 have been loaded. PWM4 controls the left motor and PWM6 the right motor. Two subroutines are provided to you. One called pwm_init will do the initialization described above. The second, called pwm_update can be used to change the rate at which the pwm is running. You can use these subroutines or create your own.